#!/usr/bin/env python
"""
Stript to build the application
Usage:
 - Windows: $ python setup.py py2exe
 - Mac:     $ python setup.py py2app
 - Linux:   $ python setup.py install
"""

import os
import sys
import glob
import shutil
from BitTornado.__init__ import product_name, version_short, home_page, author, report_email
if 'py2app' in sys.argv:
    from setuptools import setup    
else:
    if 'py2exe' in sys.argv:
        import py2exe
    from distutils.core import setup 

try:
    import psyco
    psyco.log()
    psyco.full()
except:
    print 'psyco not installed, proceeding as normal'
    
class Target(object):
    """ A simple class that holds information on our executable file. """
    def __init__(self, **kw):
        """ Default class constructor. Update as you need. """
        self.__dict__.update(kw)

class GeneralBuild(object):
    def __init__(self):
        self.name = product_name
        self.version = version_short
        self.url = home_page
        self.author = author
        self.email = report_email
        self.license = "MIT"
        self.data_files = ["icon_bt.ico", "LICENSE.txt"]

        
        self.packages = []
        self.dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll', 'tk84.dll']
        self.icon_resources = []
        self.bitmap_resources = []
        self.other_resources = []
        self.includes = []
        self.excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
                         'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
                         'Tkconstants', 'Tkinter']
        
        
        self.kargs = {'name': self.name,
                     'version': self.version,
                     'author': self.author,
                     'author_email': self.email,
                     'url': self.url,
                     'license': self.license,
                      }

    def postBuild(self):
        pass
                
class WindowsBuilder(GeneralBuild):
    def __init__(self):
        GeneralBuild.__init__(self)
        
        # Data files
        self.data_files.extend(["winsetup.nsi", "torrenticon.ico"])
        self.data_files = [(".", self.data_files)]
        # locale
        self.data_files.append(("locale",  glob.glob('locale/*.*')))
        for lang in os.listdir('locale'):
            lang_path = os.path.join('locale', lang, 'LC_MESSAGES')
            file_path = os.path.join(lang_path, 'messages.mo')
            if os.access(file_path, os.F_OK):
                self.data_files.append((lang_path, [file_path]))
        # icons
        self.data_files.append(('icons', glob.glob('icons/*.*')))
        self.data_files.append(('icons/toolbar', glob.glob('icons/toolbar/*.png')))
        self.data_files.append(('icons/preferences', glob.glob('icons/preferences/*.png')))
        self.data_files.append(('icons/status', glob.glob('icons/status/*.png')))
        self.data_files.append(('icons/misc', glob.glob('icons/misc/*.png')))
        # dlls
        py26MSdll = glob.glob("*.dll") + ["Microsoft.VC90.CRT.manifest"]
        self.data_files += [("Microsoft.VC90.CRT", py26MSdll)]


        # Icon resources
        self.icon_resources = [(1, "icon_bt.ico")]
        
        # Set Arguments
        
        self.kargs['zipfile'] = r'lib/library.zip'
        self.kargs['data_files'] = self.data_files
        self.kargs['options'] = {"py2exe": {"compressed": 2, 
                                  "optimize": 0,
                                  "includes": self.includes,
                                  "excludes": self.excludes,
                                  "packages": self.packages,
                                  "dll_excludes": self.dll_excludes,
                                  "bundle_files": 3,
                                  "dist_dir": "dist",
                                  "xref": False,
                                  "skip_archive": False,
                                  "ascii": False,
                                  "custom_boot_script": '',
                                            }
                                 }

        mainTarget = Target(
            script = "lh-abc.py",
            icon_resources = self.icon_resources,
            bitmap_resources = self.bitmap_resources,
            other_resources = self. other_resources,
            dest_base = "lh-abc",    
            version = self.version,
            company_name = self.name,
            copyright = self.author,
            name = self.name
            )
        
        cursesTarget = Target(
            script = "btlaunchmanycurses.py",
            icon_resources = self.icon_resources,
            bitmap_resources = self.bitmap_resources,
            other_resources = self. other_resources,
            dest_base = "btlaunchmanycurses",    
            version = self.version,
            company_name = self.name,
            copyright = self.author,
            name = self.name
            )
        
        consoleTarget = Target(
            script = "btlaunchmany.py",
            icon_resources = self.icon_resources,
            bitmap_resources = self.bitmap_resources,
            other_resources = self. other_resources,
            dest_base = "btlaunchmany",    
            version = self.version,
            company_name = self.name,
            copyright = self.author,
            name = self.name
            )


        self.kargs['console'] = [consoleTarget]
        self.kargs['windows'] = [mainTarget, cursesTarget]
        
    def postBuild(self):
        installer = r'"C:\Program Files\NSIS\makensis.exe"'
        os.chdir("dist")
        os.system(installer + " winsetup.nsi")
        os.system("move " + self.name + "-win32-*.exe ..")
    
class OSXBuilder(GeneralBuild):
    def __init__(self):
        GeneralBuild.__init__(self)

        # Data files
        Plist = dict(CFBundleDocumentTypes= [dict(CFBundleTypeExtensions=["torrent"],
                                                  CFBundleTypeMIMETypes = ["application/x-bittorrent"],
                                                  CFBundleTypeIconFile = "torrenticon",
                                                  CFBundleTypeName= "BitTorrent Meta-Info",
                                                  CFBundleTypeOSTypes = ["BTMF"],
                                                  NSDocumentClass = "DownloadDocument",
                                                  CFBundleTypeRole= "Viewer")],
                     CFBundleName               = self.name,
                     CFBundleShortVersionString = self.version,
                     CFBundleGetInfoString      = self.name + " " + self.version,
                     CFBundleExecutable         = self.name,
                     CFBundleIdentifier         = "com." + self.name)
        self.data_files.extend(["torrenticon.icns", "icons", "locale"])
        
        # Set Arguments
        self.kargs['app'] = ['lh-abc.py']
        self.kargs['data_files'] = self.data_files
        self.kargs['options'] = {'py2app': {'argv_emulation': True,
                                            'iconfile': 'icon_bt.icns',
                                            'plist': Plist,
                                            'site_packages': False}}
        self.kargs['setup_requires'] = ['py2app']
        
    def postBuild(self):
        # Mac dmg distribution
        if sys.platform[:6] == 'darwin':
            # Remove Old Image
            cmd = "rm -f %NAME%.dmg"
            os.system('echo Removing Old Image')
            os.system(cmd.replace('%NAME%', self.name))
            # Create New [TEMP] Image
            cmd = "hdiutil create -srcfolder dist/%NAME%.app -format UDZO -fs HFS+ -volname %NAME% %NAME%_T.dmg"
            os.system('echo Creating New [TEMP] Image')
            os.system(cmd.replace('%NAME%', self.name))
            # Convert to Compressed Image
            cmd = "hdiutil convert %NAME%_T.dmg -format UDZO -imagekey zlib-level=9 -o %NAME%.dmg"
            os.system('echo Converting to Compressed Image')
            os.system(cmd.replace('%NAME%', self.name))
            # Remove TEMP Image
            cmd = "rm -f %NAME%_T.dmg"
            os.system('echo Removing TEMP Image')
            os.system(cmd.replace('%NAME%', self.name))

class LinuxBuilder(GeneralBuild):
    def __init__(self):
        GeneralBuild.__init__(self)

        # Data files
        self.data_files.append("icon_bt.png")
        self.data_files = [('share/lh-abc', self.data_files),
                           ('share/lh-abc/locale',  glob.glob('locale/*.*')),
                           ('share/lh-abc/icons', glob.glob('icons/*.*')),
                           ('share/lh-abc/icons/toolbar', glob.glob('icons/toolbar/*.png')),
                           ('share/lh-abc/icons/preferences', glob.glob('icons/preferences/*.png')),
                           ('share/lh-abc/icons/status', glob.glob('icons/status/*.png')),
                           ('share/lh-abc/icons/misc', glob.glob('icons/misc/*.png')),
                           ('share/applications' , ['lh-abc.desktop']),
                           ]     
        for lang in os.listdir('locale'):
            lang_path = os.path.join('locale', lang, 'LC_MESSAGES')
            file_path = os.path.join(lang_path, 'messages.mo')
            if os.access(file_path, os.F_OK):
                self.data_files.append((os.path.join('share', 'lh-abc', lang_path), [file_path]))

        # Packages
        self.packages = ['BitTornado', 'BitTornado.BT1', 'LMG', 'LMG.Actions', 'LMG.GUI', 'LMG.GUI.Base',
                             'LMG.Scheduler', 'LMG.Tools', 'LMG.Torrent', 'LMG.Utility', 'khashmir']

        # Set Arguments
        self.kargs['scripts'] = ['lh-abc.py']
        self.kargs['data_files'] = self.data_files
        self.kargs['packages'] = self.packages
        self.kargs['ext_package'] = 'lh-abc'
    
if __name__ == "__main__":
    path = os.path.abspath(os.path.dirname(sys.argv[0]))
    os.chdir(path)

    builder = None
    if 'py2app' in sys.argv:
        builder = OSXBuilder()
    elif 'py2exe' in sys.argv:
        builder = WindowsBuilder()
    else:
        builder = LinuxBuilder()

    shutil.rmtree("build", ignore_errors=True)
    shutil.rmtree("dist", ignore_errors=True)
    setup(**builder.kargs)
    shutil.rmtree("build", ignore_errors=True)
    builder.postBuild()
